﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace Djs.WinForm.Components
{
    /// <summary>
    /// Různé grafické extense tříd
    /// </summary>
    public static class Extensions
    {
        #region PointF
        /// <summary>
        /// Vrátí bod, který je výsledkem výpočtu (this + add)
        /// </summary>
        /// <param name="current"></param>
        /// <param name="add"></param>
        /// <returns></returns>
        public static PointF Add(this PointF current, PointF add)
        {
            return new PointF(current.X + add.X, current.Y + add.Y);
        }
        /// <summary>
        /// Vrátí bod, který je výsledkem výpočtu (this - sub)
        /// </summary>
        /// <param name="current"></param>
        /// <param name="sub"></param>
        /// <returns></returns>
        public static PointF Sub(this PointF current, PointF sub)
        {
            return new PointF(current.X - sub.X, current.Y - sub.Y);
        }
        /// <summary>
        /// Vrátí RectangleF, který vznikne z this jako Center, s danou velikostí okolo tohoto středu
        /// </summary>
        /// <param name="current"></param>
        /// <param name="size"></param>
        /// <returns></returns>
        public static RectangleF FromCenter(this PointF current, SizeF size)
        {
            return new RectangleF(new PointF(current.X - size.Width / 2f, current.Y - size.Height / 2f), size);
        }
        #endregion
        #region RectangleF
        /// <summary>
        /// Vrátí střed daného RectangleF
        /// </summary>
        /// <param name="current"></param>
        /// <returns></returns>
        public static PointF Center(this RectangleF current)
        {
            return new PointF(current.X + current.Width / 2f, current.Y + current.Height / 2f);
        }
        /// <summary>
        /// Vrátí daný RectangleF zvětšený (zmenšený) o danou hodnotu (přičtení / odečtení dané hodnoty).
        /// Daná hodnota se přidává na všechny strany, rozměry (Width i Height) se zvětší o dvojnásobek.
        /// Hodnota může být záporná. Pokud by výsledný rozměr byl menší než 0f, upraví se na 0f.
        /// </summary>
        /// <param name="current"></param>
        /// <param name="enlargeBy"></param>
        /// <returns></returns>
        public static RectangleF Enlarge(this RectangleF current, float enlargeBy)
        {
            return current.Enlarge(enlargeBy, enlargeBy);
        }
        /// <summary>
        /// Vrátí daný RectangleF zvětšený (zmenšený) o danou hodnotu (přičtení / odečtení dané hodnoty).
        /// Naproti tomu metoda Expand() vrátí RectangleF upravený koeficientem (násobením).
        /// Daná hodnota se přidává na všechny strany, rozměry (Width i Height) se zvětší o dvojnásobek.
        /// Hodnota může být záporná. Pokud by výsledný rozměr byl menší než 0f, upraví se na 0f.
        /// </summary>
        /// <param name="current"></param>
        /// <param name="enlargeByX"></param>
        /// <param name="enlargeByY"></param>
        /// <returns></returns>
        public static RectangleF Enlarge(this RectangleF current, float enlargeByX, float enlargeByY)
        {
            if ((current.Width + 2f * enlargeByX) < 0f)
                enlargeByX = -current.Width / 2f;
            if ((current.Height + 2f * enlargeByY) < 0f)
                enlargeByY = -current.Height / 2f;

            return new RectangleF(current.X - enlargeByX, current.Y - enlargeByY, current.Width + 2f * enlargeByX, current.Height + 2f * enlargeByY);
        }
        /// <summary>
        /// Vrátí daný RectangleF zvětšený (zmenšený) daným koeficientem (násobení danou hodnotou).
        /// Naproti tomu metoda Enlarge() vrátí RectangleF upravený přičtením hodnoty.
        /// Daná hodnota se přidává na všechny strany, rozměry (Width i Height) se zvětší o dvojnásobek přídavku.
        /// Hodnota smí být menší než 1 (dojde ke zmenšení), ale nesmí být záporná, protože by rozměr vyšel záporný.
        /// </summary>
        /// <param name="current"></param>
        /// <param name="expandBy"></param>
        /// <returns></returns>
        public static RectangleF Expand(this RectangleF current, float expandBy)
        {
            return current.Expand(expandBy, expandBy);
        }
        /// <summary>
        /// Vrátí daný RectangleF zvětšený (zmenšený) daným koeficientem (násobení danou hodnotou).
        /// Naproti tomu metoda Enlarge() vrátí RectangleF upravený přičtením hodnoty.
        /// Daná hodnota se přidává na všechny strany, rozměry (Width i Height) se zvětší o dvojnásobek přídavku.
        /// Hodnota smí být menší než 1 (dojde ke zmenšení), ale nesmí být záporná, protože by rozměr vyšel záporný.
        /// </summary>
        /// <param name="current"></param>
        /// <param name="expandByX"></param>
        /// <param name="expandByY"></param>
        /// <returns></returns>
        public static RectangleF Expand(this RectangleF current, float expandByX, float expandByY)
        {
            return current.Enlarge(current.Width * expandByX, current.Height * expandByY);
        }
        #endregion
    }
}
